<html>
<head>
<title>C++ Annotations Version 6.5.0</title>
</head>
<body text="black" bgcolor="white">
<hr>
<ul>
    <li> <a href="cplusplus.html">Table of Contents</a>
    <li> <a href="cplusplus15.html">Previous Chapter</a>
    <li> <a href="cplusplus17.html">Next Chapter</a>
</ul>
<hr>
<a name="NESTEDCLASSES"></a><a name="l221"></a>
<h1>Chapter 16: Nested Classes</h1>
<a name="nested"></a>
<blockquote>
    <em>
        Don't hesitate to send in feedback: send an e-mail if you like the
        C++ Annotations; if you think that important material was omitted;
        if you find errors or typos in the text or the code examples;
        or if you just feel like e-mailing. Send your e-mail to
        <a href="mailto:f.b.brokken@rug.nl">Frank B. Brokken</a>.
<p>
<strong>Please</strong> state the document version you're referring to, as found in
        the title (in this document: 6.5.0) and please state chapter and
        paragraph name or number you're referring to.
<p>
All received mail is processed conscientiously, and received
        suggestions for improvements will usually have been processed by the
        time a new version of the Annotations is released. Except for the
        incidental case I will normally not acknowledge the receipt of
        suggestions for improvements. Please don't interpret this as me not
        appreciating your efforts.
    </em>
</blockquote>
<p>
<a name="nested/nesting"></a>Classes can be defined inside other classes. Classes that are defined inside
other classes are called <a name="an2134"></a>
 <em>nested classes</em>. Nested classes
are used in situations where the nested class has a close conceptual
relationship to its surrounding class. For example, with the class <code>string</code>
a type <a name="an2135"></a>
<code>string::iterator</code> is available which will provide all characters
that are stored in the <code>string</code>. This <code>string::iterator</code> type could be
defined as an object <a name="an2136"></a>
<code>iterator</code>, defined as nested class in the class
<code>string</code>.
<p>
A class can be nested in every part of the surrounding class: in the
<code>public, protected</code> or <code>private</code> section. Such a nested class can be
considered a member <a name="an2137"></a>
 of the surrounding class. The
normal access and  rules in classes apply to nested classes. If a
class is nested in the <code>public</code> section of a class, it is
    <a name="an2138"></a>
 visible outside the surrounding class. If
it is nested in the <code>protected</code> section it is visible in subclasses, derived
from the surrounding class (see chapter <a href="cplusplus13.html#INHERITANCE">13</a>), if it is nested in
the <code>private</code> section, it is only visible for the members of the surrounding
class.
<p>
The surrounding class has no special privileges with respect to the nested
class. So, the nested class still has full control over the accessibility of
its members by the surrounding class. For example, consider the following
class definition:
        <pre>
    class Surround
    {
        public:
            class FirstWithin
            {
                int d_variable;

                public:
                    FirstWithin();
                    int var() const;
            };
        private:
            class SecondWithin
            {
                int d_variable;

                public:
                    SecondWithin();
                    int var() const;
            };
    };
    inline int Surround::FirstWithin::var() const
    {
        return d_variable;
    }
    inline int Surround::SecondWithin::var() const
    {
        return d_variable;
    }
</pre>
    In this definition access to the members is defined as follows:
        <ul>
        <li> The class <code>FirstWithin</code> is visible both outside and inside
<code>Surround</code>. The class <code>FirstWithin</code> therefore has  global scope.
        <li> The constructor <code>FirstWithin()</code> and the member function
<code>var()</code> of the class <code>FirstWithin</code> are also globally visible.
        <li> The <code>int d_variable</code> datamember is only visible to the members
of the class <code>FirstWithin</code>. Neither the members of <code>Surround</code> nor the
members of <code>SecondWithin</code> can access <code>d_variable</code> of the class
<code>FirstWithin</code> directly.
        <li> The class <code>SecondWithin</code> is only visible inside
<code>Surround</code>. The public members of the class <code>SecondWithin</code> can also be
used by the members of the class <code>FirstWithin</code>, as nested classes can be
considered members of their surrounding class.
        <li> The constructor <code>SecondWithin()</code> and the member function
<code>var()</code> of the class <code>SecondWithin</code> can also only be reached by the
members of <code>Surround</code> (and by the members of its nested classes).
        <li> The <code>int d_variable</code> datamember of the class <code>SecondWithin</code>
is only visible to the members of the class <code>SecondWithin</code>. Neither the
members of <code>Surround</code> nor the members of <code>FirstWithin</code> can access
<code>d_variable</code> of the class <code>SecondWithin</code> directly.
        <li> As always, an object of the class type is required before
its members can be called. This also holds true for nested classes.
        </ul>
    If the surrounding class should have access rights to the private members
of its nested classes or if nested classes should have access rights to the
private members of the surrounding class, the classes can be defined as
<code>friend</code> classes (see section <a href="cplusplus16.html#NESTEDFRIENDS">16.3</a>).
<p>
The nested classes can be considered members of the surrounding class, but
the <a name="an2139"></a>
members of nested classes are <em>not</em> members of the surrounding
class. So, a member of the class <code>Surround</code> may not access
<code>FirstWithin::var()</code> directly. This is understandable considering the fact
that a <code>Surround</code> object is not also a <code>FirstWithin</code> or <code>SecondWithin</code>
object. In fact, nested classes are just typenames. It is not implied that
objects of such classes automatically exist in the surrounding class. If a
member of the surrounding class should use a (non-static) member of a nested
class then the surrounding class must define a nested class object, which can
thereupon be used by the members of the surrounding class to use members of
the nested class.
<p>
For example, in the following class definition there is a surrounding
class <code>Outer</code> and a nested class <code>Inner</code>. The class <code>Outer</code> contains a
member function <code>caller()</code> which uses the <code>inner</code> object that is composed
in <code>Outer</code> to call the <code>infunction()</code> member function of <code>Inner</code>:
        <pre>
    class Outer
    {
        public:
            void caller();

        private:
            class Inner
            {
                public:
                    void infunction();
            };
            Inner d_inner;      // class Inner must be known
    };
    void Outer::caller()
    {
        d_inner.infunction();
    }
</pre>
    The mentioned function <code>Inner::infunction()</code> can be called as part
of the inline definition of <code>Outer::caller()</code>, even though the definition of
the class <code>Inner</code> is yet to be seen by the compiler.  On the other hand, the
compiler must have seen the definition of the class <code>Inner</code> before a data
member of that class can be defined.
<p>
<a name="l222"></a>
<h2>16.1: Defining nested class members</h2>
<a name="nested/defining"></a>Member functions of nested classes may be defined as inline functions.  Inline
<a name="an2140"></a>
 member functions can be defined as if they were
functions defined outside of the class definition: if the function
<code>Outer::caller()</code> would have been defined outside of the class <code>Outer</code>,
the full class definition (including the definition of the class <code>Inner</code>)
would have been available to the compiler. In that situation the function is
perfectly compilable. Inline functions can be compiled accordingly: they can
be defined and they can use any nested class. Even if it appears later in the
class interface.
<p>
As shown, when (nested) member functions are defined inline, their definition
should be put below their class interface. Static nested data members
are also normally defined outside of their classes.
    <a name="an2141"></a>

        If the class <code>FirstWithin</code> would have a <code>static size_t</code> datamember
<code>epoch</code>, it could be initialized as follows:
        <pre>
    size_t Surround::FirstWithin::epoch = 1970;
</pre>
    Furthermore, multiple <a name="an2142"></a>
 scope resolution
operators are needed to refer to public static members in code outside of the
surrounding class:
        <pre>
    void showEpoch()
    {
        cout &lt;&lt; Surround::FirstWithin::epoch = 1970;
    }
</pre>
    Inside the members of the class <code>Surround</code> only the <code>FirstWithin::</code>
scope must be used; inside the members of the class <code>FirstWithin</code> there is
no need to refer explicitly to the scope.
<p>
What about the members of the class <code>SecondWithin</code>? The classes
<code>FirstWithin</code> and <code>SecondWithin</code> are both nested within <code>Surround</code>, and
can be considered members of the surrounding class. Since members of a class
may directly refer to each other, members of the class <code>SecondWithin</code> can
refer to (public) members of the class <code>FirstWithin</code>. Consequently, members
of the class <code>SecondWithin</code> could refer to the <code>epoch</code> member of
<code>FirstWithin</code> as
     <pre>
        FirstWithin::epoch
</pre>
<p>
<a name="l223"></a>
<h2>16.2: Declaring nested classes</h2>
<a name="nested/declaring"></a>Nested classes <a name="an2143"></a>
 may be declared before they are
actually defined in a surrounding class. Such <a name="an2144"></a>
forward declarations are
required if a class contains multiple nested classes, and the nested classes
contain pointers, references, parameters or return values to objects of the
other nested classes.
<p>
For example, the following class <code>Outer</code> contains two nested classes
<code>Inner1</code> and <code>Inner2</code>. The class <code>Inner1</code> contains a pointer to
<code>Inner2</code> objects, and <code>Inner2</code> contains a pointer to <code>Inner1</code>
objects. Such cross references require forward declarations. These forward
declarations must be specified in the same access-category as their actual
definitions. In the following example the <code>Inner2</code> forward declaration must
be given in a <code>private</code> section, as its definition is also part of the
class <code>Outer</code>'s private interface:
        <pre>
    class Outer
    {
        private:
            class Inner2;       // forward declaration

            class Inner1
            {
                Inner2 *pi2;    // points to Inner2 objects
            };
            class Inner2
            {
                Inner1 *pi1;    // points to Inner1 objects
            };
    };
</pre>
<p>
<a name="NESTEDFRIENDS"></a><a name="l224"></a>
<h2>16.3: Accessing private members in nested classes</h2>
<a name="nested/nestedfriends"></a>    To allow nested classes to access the <a name="an2145"></a>
private members of
their surrounding class; to access the private members of other nested classes;
or to allow the surrounding class to access the private members of its nested
classes, the <a name="an2146"></a>
<code>friend</code> keyword must be used. Consider the following
situation, in which a class <code>Surround</code> has two nested classes
<code>FirstWithin</code> and <code>SecondWithin</code>, while each class has a
    <a name="an2147"></a>
static data member <code>int s_variable</code>:
        <pre>
    class Surround
    {
        static int s_variable;
        public:
            class FirstWithin
            {
                static int s_variable;
                public:
                    int value();
            };
            int value();
        private:
            class SecondWithin
            {
                static int s_variable;
                public:
                    int value();
            };
    };
</pre>
    If the class <code>Surround</code> should be able to access <code>FirstWithin</code> and
<code>SecondWithin</code>'s private members, these latter two classes must declare
<code>Surround</code> to be their friend. The function <code>Surround::value()</code> can
thereupon access the private members of its nested classes. For example (note
the <code>friend</code> declarations in the two nested classes):
        <pre>
    class Surround
    {
        static int s_variable;
        public:
            class FirstWithin
            {
                friend class Surround;
                static int s_variable;
                public:
                    int value();
            };
            int value();
        private:
            class SecondWithin
            {
                friend class Surround;
                static int s_variable;
                public:
                    int value();
            };
    };
    inline int Surround::FirstWithin::value()
    {
        FirstWithin::s_variable = SecondWithin::s_variable;
        return (s_variable);
    }
</pre>
    Now, to allow the nested classes access to the private members of
their surrounding class, the class <code>Surround</code> must declare its nested classes
as friends. The <code>friend</code> keyword may only be used when the class that is to
become a friend is already known as a class by the compiler, so either a
<a name="an2148"></a>
forward declaration of the nested classes is required, which is followed
by the friend declaration, or the friend declaration follows the definition of
the nested classes. The forward declaration followed by the friend declaration
looks like this:
        <pre>
    class Surround
    {
        class FirstWithin;
        class SecondWithin;
        friend class FirstWithin;
        friend class SecondWithin;

        public:
            class FirstWithin;
        ...
</pre>
    Alternatively, the friend declaration may follow the definition of the
classes. Note that a class can be declared a friend following its definition,
while the inline code in the definition already uses the fact that it will be
declared a friend of the outer class. When defining members within the class
interface implementations of nested class members may use members of the
surrounding class that have not yet been seen by the compiler. Finally note
that q`<code>s_variable</code>' which is
    <a name="an2149"></a>
 defined in the class <code>Surround</code> is
accessed in the nested classes as <code>Surround::s_variable</code>:
        <pre>
    class Surround
    {
        static int s_variable;
        public:
            class FirstWithin
            {
                friend class Surround;
                static int s_variable;
                public:
                    int value();
            };
            friend class FirstWithin;
            int value();

        private:
            class SecondWithin
            {
                friend class Surround;
                static int s_variable;
                public:
                    int value();
            };
            static void classMember();

            friend class SecondWithin;
    };

    inline int Surround::value()
    {
        FirstWithin::s_variable = SecondWithin::s_variable;
        return s_variable;
    }

    inline int Surround::FirstWithin::value()
    {
        Surround::s_variable = 4;
        Surround::classMember();
        return s_variable;
    }

    inline int Surround::SecondWithin::value()
    {
        Surround::s_variable = 40;
        return s_variable;
    }
</pre>
    Finally, we want to allow the nested classes access to each other's
private members. Again this requires some <code>friend</code> declarations. In order to
allow <code>FirstWithin</code> to access <code>SecondWithin</code>'s private members nothing but
a <code>friend</code> declaration in <code>SecondWithin</code> is required. However, to allow
<code>SecondWithin</code> to access the private members of <code>FirstWithin</code> the
<code>friend class SecondWithin</code> declaration cannot plainly be given in the class
<code>FirstWithin</code>, as the definition of <code>SecondWithin</code> is as yet unknown. A
<a name="an2150"></a>
forward declaration of <code>SecondWithin</code> is required, and this forward
declaration must be provided by the class <code>Surround</code>, rather than by the
class <code>FirstWithin</code>.
<p>
Clearly, the forward declaration <code>class SecondWithin</code> in the class
<code>FirstWithin</code> itself makes no sense, as this would refer to an external
(global) class <code>SecondWithin</code>. Likewise, it is impossible to provide the
forward declaration of the nested class <code>SecondWithin</code> inside
<code>FirstWithin</code> as <code>class Surround::SecondWithin</code>, with the compiler issuing
a message like
        <pre>
        `Surround' does not have a nested type named `SecondWithin'
</pre>
    The proper procedure here is to declare the class <code>SecondWithin</code> in the
class <code>Surround</code>, before the class <code>FirstWithin</code> is defined. Using this
procedure, the friend declaration of <code>SecondWithin</code> is accepted inside the
definition of <code>FirstWithin</code>. The following class definition allows full
access of the private members of all classes by all other classes:
        <pre>
    class Surround
    {
        class SecondWithin;
        static int s_variable;
        public:
            class FirstWithin
            {
                friend class Surround;
                friend class SecondWithin;
                static int s_variable;
                public:
                    int value();
            };
            friend class FirstWithin;
            int value();
        private:
            class SecondWithin
            {
                friend class Surround;
                friend class FirstWithin;
                static int s_variable;
                public:
                    int value();
            };
            friend class SecondWithin;
    };
    inline int Surround::value()
    {
        FirstWithin::s_variable = SecondWithin::s_variable;
        return s_variable;
    }

    inline int Surround::FirstWithin::value()
    {
        Surround::s_variable = SecondWithin::s_variable;
        return s_variable;
    }

    inline int Surround::SecondWithin::value()
    {
        Surround::s_variable = FirstWithin::s_variable;
        return s_variable;
    }
</pre>
<p>
<a name="l225"></a>
<h2>16.4: Nesting enumerations</h2>
<a name="nested/enumerations"></a>Enumerations too <a name="an2151"></a>
 <a name="an2152"></a>
 may be nested
in classes. Nesting enumerations is a good way to show the close connection
between the enumeration and its class. In the class <a name="an2153"></a>
<code>ios</code> we've seen values
like <a name="an2154"></a>
<code>ios::beg</code> and <a name="an2155"></a>
<code>ios::cur</code>. In the current <a name="an2156"></a>
Gnu <strong>C++</strong>
implementation these values are defined as values in the <a name="an2157"></a>
<code>seek_dir</code>
enumeration:
        <pre>
    class ios: public _ios_fields
    {
        public:
            enum seek_dir
            {
                beg,
                cur,
                end
            };
    };
</pre>
    For illustration purposes, let's assume that a class <code>DataStructure</code>
may be traversed in a forward or backward direction. Such a class can define
an enumeration <code>Traversal</code> having the values <code>forward</code> and
<code>backward</code>. Furthermore, a member function <code>setTraversal()</code> can be defined
requiring either of the two enumeration values. The class can be defined as
follows:
        <pre>
    class DataStructure
    {
        public:
            enum Traversal
            {
                forward,
                backward
            };
            setTraversal(Traversal mode);
        private:
            Traversal
                d_mode;
    };
</pre>
    Within the class <code>DataStructure</code> the values of the <code>Traversal</code>
enumeration can be used directly. For example:
        <pre>
    void DataStructure::setTraversal(Traversal mode)
    {
        d_mode = mode;
        switch (d_mode)
        {
            forward:
            break;

            backward:
            break;
        }
    }
</pre>
    Ouside of the class <code>DataStructure</code> the name of the enumeration type is
not used to refer to the values of the enumeration. Here the classname is
sufficient. Only if a variable of the enumeration type is required the name of
the enumeration type is needed, as illustrated by the following piece of code:
        <pre>
    void fun()
    {
        DataStructure::Traversal                // enum typename required
            localMode = DataStructure::forward; // enum typename not required

        DataStructure ds;
                                                // enum typename not required
        ds.setTraversal(DataStructure::backward);
    }
</pre>
    Again, only if <code>DataStructure</code> defines a nested class <code>Nested</code>, in
turn defining the enumeration <code>Traversal</code>, the two class scopes are
required. In that case the latter example should have been coded as follows:
        <pre>
    void fun()
    {
        DataStructure::Nested::Traversal
            localMode = DataStructure::Nested::forward;

        DataStructure ds;

        ds.setTraversal(DataStructure::Nested::backward);
    }
</pre>
<p>
<a name="EMPTYENUM"></a><a name="l226"></a>
<h3>16.4.1: Empty enumerations</h3>
    <a name="nested/emptyenum"></a>    <code>Enum</code> types usually have values. However, this is not required. In
section <a href="cplusplus14.html#DYNAMICCAST">14.5.1</a> the <a name="an2158"></a>
<code>std::bad_cast</code> type was introduced. A
<code>std::bad_cast</code> is thrown by the <a name="an2159"></a>
<code>dynamic_cast&lt;&gt;()</code> operator when a
reference to a <a name="an2160"></a>
base class object cannot be cast to a <a name="an2161"></a>
derived class
reference. The <code>std::bad_cast</code> could be caught as type, irrespective of any
value it might represent.
<p>
Actually, it is not even necessary for a <a name="an2162"></a>
 type to
contain values. It is possible to define an <a name="an2163"></a>
<em>empty enum</em>, an <code>enum</code>
without any values, whose name may thereupon be used as a legitimate type name
in, e.g. a <a name="an2164"></a>
<code>catch</code> clause defining an <a name="an2165"></a>
exception handler.
<p>
An empty <code>enum</code> is defined as follows (often, but not necessarily within
a <a name="an2166"></a>
<code>class</code>):
        <pre>
    enum EmptyEnum
    {};
</pre>
    Now an <code>EmptyEnum</code> may be thrown (and caught) as an exception:
        <pre>
    #include &lt;iostream&gt;

    enum EmptyEnum
    {};

    using namespace std;

    int main()
    try
    {
        throw EmptyEnum();
    }
    catch (EmptyEnum)
    {
        cout &lt;&lt; "Caught empty enum\n";
    }
    /*
        Generated output:

        Caught empty enum
    */
</pre>
<p>
<a name="NESTEDVIRTCONS"></a><a name="l227"></a>
<h2>16.5: Revisiting virtual constructors</h2>
<a name="nested/virtcons.yo"></a>In section <a href="cplusplus14.html#VIRTCONS">14.10</a> the notion of virtual constructors was introduced. In
that section a class <code>Base</code> was used as an abstract base class. A class
<code>Clonable</code> was thereupon defined to manage <code>Base</code> class pointers in
containers like vectors.
<p>
As the class <code>Base</code> is a very small class, hardly requiring any
implementation, it can well be defined as a nested class in <code>Clonable</code>. This
will emphasize the close relationship that exists between <code>Clonable</code> and
<code>Base</code>, as shown by the way classes are derived from <code>Base</code>. One no longer
writes:
        <pre>
    class Derived: public Base
</pre>
but rather:
        <pre>
    class Derived: public Clonable::Base
</pre>
    Other than defining <code>Base</code> as a nested class, and deriving from
<code>Clonable::Base</code> rather than from <code>Base</code>, nothing needs to be
modified. Here is the program shown earlier in section <a href="cplusplus14.html#VIRTCONS">14.10</a>, but now
using nested classes:
        <pre>
    #include &lt;iostream&gt;
    #include &lt;vector&gt;
    #include &lt;typeinfo&gt;

    class Clonable
    {
        public:
            class Base
            {
                public:
                    virtual ~Base();
                    virtual Base *clone() const = 0;
            };

        private:
            Base *d_bp;

        public:
            Clonable();
            ~Clonable();
            Clonable(Clonable const &amp;other);
            Clonable &amp;operator=(Clonable const &amp;other);

            // New for virtual constructions:
            Clonable(Base const &amp;bp);
            Base &amp;get() const;

        private:
            void copy(Clonable const &amp;other);
    };


    inline Clonable::Base::~Base()
    {}

    inline Clonable::Clonable()
    :
        d_bp(0)
    {}
    inline Clonable::~Clonable()
    {
        delete d_bp;
    }
    inline Clonable::Clonable(Clonable const &amp;other)
    {
        copy(other);
    }
    inline Clonable &amp;Clonable::operator=(Clonable const &amp;other)
    {
        if (this != &amp;other)
        {
            delete d_bp;
            copy(other);
        }
        return *this;
    }

    inline Clonable::Clonable(Base const &amp;bp)
    {
        d_bp = bp.clone();      // allows initialization from
    }                           // Base and derived objects

    inline Clonable::Base &amp;Clonable::get() const
    {
        return *d_bp;
    }

    inline void Clonable::copy(Clonable const &amp;other)
    {
        if ((d_bp = other.d_bp))
            d_bp = d_bp-&gt;clone();
    }

    class Derived1: public Clonable::Base
    {
        public:
            ~Derived1();
            virtual Clonable::Base *clone() const;
    };

    inline Derived1::~Derived1()
    {
        std::cout &lt;&lt; "~Derived1() called\n";
    }
    inline Clonable::Base *Derived1::clone() const
    {
        return new Derived1(*this);
    }

    using namespace std;

    int main()
    {
        vector&lt;Clonable&gt; bv;

        bv.push_back(Derived1());
        cout &lt;&lt; "==\n";

        cout &lt;&lt; typeid(bv[0].get()).name() &lt;&lt; endl;
        cout &lt;&lt; "==\n";

        vector&lt;Clonable&gt; v2(bv);
        cout &lt;&lt; typeid(v2[0].get()).name() &lt;&lt; endl;
        cout &lt;&lt; "==\n";
    }
</pre>
<p>

<hr>
<ul>
    <li> <a href="cplusplus.html">Table of Contents</a>
    <li> <a href="cplusplus15.html">Previous Chapter</a>
    <li> <a href="cplusplus17.html">Next Chapter</a>
</ul>
<hr>
</body>
</html>
